package com.farm.web.restful;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.farm.authority.service.UserServiceInter;
import com.farm.core.page.ViewMode;
import com.farm.file.FarmFileServiceInter;
import com.farm.file.domain.FileBase;
import com.farm.file.enums.FileModel;
import com.farm.file.exception.FileExNameException;
import com.farm.file.exception.FileSizeException;
import com.farm.file.service.FileBaseServiceInter;
import com.farm.file.util.FarmDocFiles;
import com.farm.file.util.FileCopyProcessCache;
import com.farm.parameter.FarmParameterService;
import com.farm.web.WebUtils;

/**
 * 文件服务接口
 * 
 * @author autoCode
 * 
 */
@RequestMapping("/fileapi")
@Controller
public class FileApiController extends WebUtils {
	private static final Logger log = Logger.getLogger(FileApiController.class);
	@Resource
	private FarmFileServiceInter farmFileServiceImpl;
	@Resource
	private UserServiceInter userServiceImpl;
	@Resource
	private FileBaseServiceInter fileBaseServiceImpl;

	@RequestMapping("/file/property")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> getProperty(String operatorLoginname, String operatorPassword,
			String secret, HttpServletRequest request) {
		try {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("FILESIZE", FarmParameterService.getInstance().getParameterLong("config.doc.upload.length.max"));
			map.put("IMGSIZE", FarmParameterService.getInstance().getParameterLong("config.doc.img.upload.length.max"));
			map.put("FILETYPE", FarmParameterService.getInstance().getParameter("config.doc.upload.types"));
			map.put("IMGTYPE", FarmParameterService.getInstance().getParameter("config.doc.img.upload.types"));
			map.put("MEDIATYPE", FarmParameterService.getInstance().getParameter("config.doc.media.upload.types"));
			return ViewMode.getInstance().putAttr("DATA", map).returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 获得一个附件空间
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/file/init")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> initFileSpace(String operatorLoginname, String operatorPassword,
			String filename, Long length, String appid, String secret, HttpServletRequest request) {
		try {
			log.info("restful API:获得一个附件空间" + length);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			FileBase file = farmFileServiceImpl.initFile(userServiceImpl.getUserByLoginName(operatorLoginname),
					filename, length, appid, operatorLoginname);
			String realpath = farmFileServiceImpl.getFileRealPath(file.getId());
			return ViewMode.getInstance().putAttr("realpath", realpath).putAttr("fileid", file.getId())
					.returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 兑换一个AppId为fileId
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/appid/tofileid")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> byAppid(String operatorLoginname, String operatorPassword, String appid,
			String secret, HttpServletRequest request) {
		ViewMode view = ViewMode.getInstance();
		try {
			log.info("restful API:兑换一个AppId为fileId,appid=" + appid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			String fileid = farmFileServiceImpl.getFileIdByAppId(appid);
			FileBase filebase = farmFileServiceImpl.getFileBase(fileid);
			if (filebase != null) {
				view.putAttr("FILESTATE", filebase.getPstate());
			}
			return view.putAttr("DATA", fileid).returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 提交一個臨時文件為持久化文件
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/file/submit")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> submit(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:提交持久化一個文件" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			farmFileServiceImpl.submitFile(fileid);
			return ViewMode.getInstance().returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 將一個持久化文件轉爲臨時文件
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/file/free")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> free(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:釋放一個文件為臨時文件" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			farmFileServiceImpl.freeFile(fileid);
			return ViewMode.getInstance().returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 逻辑删除臨時文件
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/file/del")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> del(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:邏輯刪除一個文件" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			farmFileServiceImpl.delFileByLogic(fileid);
			return ViewMode.getInstance().returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 獲得文件信息
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/file/info")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> info(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:獲得文件信息" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			return ViewMode.getInstance().putAttr("info", farmFileServiceImpl.getFileInfo(fileid)).returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 获得图标下载地址
	 * 
	 * @param operatorLoginname
	 * @param operatorPassword
	 * @param fileid            fileid或appid必填
	 * @param appid             业务id
	 * @param secret
	 * @param request
	 * @return Map<String,Object>
	 */
	@RequestMapping("/url/icon")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> icon(String operatorLoginname, String operatorPassword, String fileid,
			String appid, String secret, HttpServletRequest request) {
		try {
			log.info("restful API:获得图标下载地址" + fileid);
			if (StringUtils.isNotBlank(appid)) {
				fileid = farmFileServiceImpl.getFileIdByAppId(appid);
			}
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			return ViewMode.getInstance().putAttr("url", farmFileServiceImpl.getIconUrl(fileid)).returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 获得文件下载地址
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/url/download")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> download(String operatorLoginname, String operatorPassword,
			String fileid, String secret, HttpServletRequest request) {
		try {
			log.info("restful API:获得文件下载地址" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			return ViewMode.getInstance()
					.putAttr("url",
							farmFileServiceImpl.getDownloadUrl(fileid, farmFileServiceImpl.getFileModel(fileid)))
					.returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 获得媒体文件播放地址
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/url/play")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> play(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:获得文件播放地址" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			return ViewMode.getInstance()
					.putAttr("url", farmFileServiceImpl.getPlayUrl(fileid, farmFileServiceImpl.getFileModel(fileid)))
					.returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 获得文件的文本信息
	 * 
	 * @param session
	 * @return Map<String,Object>
	 */
	@RequestMapping("/text")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> text(String operatorLoginname, String operatorPassword, String fileid,
			String secret, HttpServletRequest request) {
		try {
			log.info("restful API:获得文件的文本信息" + fileid);
			ApiController.checkSecret(secret, request);
			ApiController.checkAuth(operatorLoginname, operatorPassword);
			return ViewMode.getInstance().putAttr("text", farmFileServiceImpl.getFiletext(fileid)).returnJsonMode();
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e).returnJsonMode();
		}
	}

	/**
	 * 上传附件文件
	 * 
	 * @param file
	 * @param fileid
	 * @param operatorLoginname
	 * @param operatorPassword
	 * @param secret
	 * @param processkey
	 * @param request
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/file/upload")
	@ResponseBody
	public Map<String, Object> upload(@RequestParam(value = "file", required = false) MultipartFile file, String fileid,
			String operatorLoginname, String operatorPassword, String secret, String processkey,
			HttpServletRequest request, HttpSession session) {
		FileBase filebase = null;
		String url = null;
		ViewMode view = ViewMode.getInstance();
		try {
			filebase = farmFileServiceImpl.getFileBase(fileid);
			FileModel fileModel = FileModel.getModel(filebase.getTitle());

			// 校验文件长度
			if (!fileBaseServiceImpl.validateFileSize(file.getSize(), fileModel)) {
				throw new FileSizeException("the file max size is " + fileModel.getMaxsize());
			}
			// 校驗文件類型
			if (!fileBaseServiceImpl.validateFileExname(filebase.getTitle(), fileModel)) {
				throw new FileExNameException(
						"the file type is not exist " + StringUtils.join(fileModel.getExnames(), ","));
			}
			CommonsMultipartFile cmFile = (CommonsMultipartFile) file;
			DiskFileItem item = (DiskFileItem) cmFile.getFileItem();
			{// 小于8k不生成到临时文件，临时解决办法。zhanghc20150919
				if (!item.getStoreLocation().exists()) {
					try {
						item.write(item.getStoreLocation());
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
				}
			}
			FarmDocFiles.copyFile(item.getStoreLocation(), fileBaseServiceImpl.getDirRealPath(filebase.getId()),
					filebase.getFilename(), processkey);
			url = farmFileServiceImpl.getDownloadUrl(filebase.getId(), fileModel);
			String filename = URLEncoder.encode(filebase.getTitle(), "utf-8").replaceAll("\\+", "%20");
			farmFileServiceImpl.updateFilesize(fileid, (int) file.getSize());
			view.putAttr("fileName", filename);
			view.putAttr("id", filebase.getId());
			view.putAttr("url", url);
		} catch (FileSizeException e) {
			view.setError("文件大小错误:" + e.getMessage(), e);
		} catch (FileExNameException e) {
			view.setError("文件类型错误:" + e.getMessage(), e);
		} catch (UnsupportedEncodingException e) {
			view.setError(e.getMessage(), e);
		}
		return view.returnObjMode();
	}

	@RequestMapping(value = "/file/process")
	@ResponseBody
	public Map<String, Object> PubUploadProcess(String processkey, HttpSession session) {
		ViewMode view = ViewMode.getInstance();
		Integer process = 0;
		try {
			process = FileCopyProcessCache.getProcess(processkey);
			if (process == null) {
				process = 0;
			}
		} catch (Exception e) {
			view.setError(e.getMessage(), e);
		}
		return view.putAttr("PROCESS", process).returnObjMode();
	}
}
